#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <psp2/kernel/processmgr.h>

#include "patch.h"

int *(*SystemExecute)(void);
int *(*SetVFunctionGroup)(int *result);

int *SystemExecute_hook(void)
{
    int *ret = SystemExecute();

    int32_t SysLevel = *(int32_t *)(LOAD_ADDRESS + 0x001C3C68);
    int32_t SysPage = *(int32_t *)(LOAD_ADDRESS + 0x001C3C64);
    int32_t fUse = *(int32_t *)(LOAD_ADDRESS + 0x001C3C6C);
    int32_t fUse2 = *(int32_t *)(LOAD_ADDRESS + 0x001C3C70);

    if (SysPage == 4 && SysLevel == 2 && fUse == 0 && fUse2 == 30)
    {
        // 修正结束游戏
        // printf("SystemExecute ExitProcess: SysLevel: %d, SysPage: %d, fUse: %d, fUse2: %d\n", SysLevel, SysPage, fUse, fUse2);
        sceKernelExitProcess(0);
    }

    return ret;
}

int *j_SetVFunctionGroup(int *result)
{
    int *ret = SetVFunctionGroup(result);

    int32_t *fExecute = (int32_t *)(LOAD_ADDRESS + 0x001C1230);
    if (*fExecute == (int32_t)SystemExecute) // SystemExecute
        *fExecute = (int32_t)SystemExecute_hook;

    return ret;
}

int initPatchSetting()
{
    SystemExecute = (void *)so_symbol(&so_mod, "_Z13SystemExecutev");
    SetVFunctionGroup = (void *)so_symbol(&so_mod, "_Z17SetVFunctionGroupi");

    hook_addr((uintptr_t)(LOAD_ADDRESS + 0x00109940), (uintptr_t)&j_SetVFunctionGroup);

    return 0;
}
